home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / liboctave / idx-vector.cc < prev    next >
C/C++ Source or Header  |  1997-08-01  |  10KB  |  582 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #if defined (__GNUG__)
  24. #pragma implementation
  25. #endif
  26.  
  27. #ifdef HAVE_CONFIG_H
  28. #include <config.h>
  29. #endif
  30.  
  31. #include <cstdlib>
  32.  
  33. #include <iostream.h>
  34.  
  35. #include "Range.h"
  36. #include "dColVector.h"
  37. #include "dMatrix.h"
  38.  
  39. #include "idx-vector.h"
  40. #include "lo-error.h"
  41. #include "lo-mappers.h"
  42.  
  43. #define IDX_VEC_REP idx_vector::idx_vector_rep
  44.  
  45. IDX_VEC_REP::idx_vector_rep (const IDX_VEC_REP& a)
  46. {
  47.   data = 0;
  48.   initialized = a.initialized;
  49.   frozen = a.frozen;
  50.   colon_equiv_checked = a.colon_equiv_checked;
  51.   colon_equiv = a.colon_equiv;
  52.  
  53.   colon = a.colon;
  54.  
  55.   orig_nr = a.orig_nr;
  56.   orig_nc = a.orig_nc;
  57.  
  58.   len = a.len;
  59.   if (len > 0)
  60.     {
  61.       data = new int [len];
  62.       for (int i = 0; i < len; i++)
  63.     data[i] = a.data[i];
  64.  
  65.       num_zeros = a.num_zeros;
  66.       num_ones = a.num_ones;
  67.       one_zero = a.one_zero;
  68.  
  69.       max_val = a.max_val;
  70.       min_val = a.min_val;
  71.     }
  72. }
  73.  
  74. static inline int
  75. tree_to_mat_idx (double x)
  76. {
  77.   return (x > 0) ? ((int) (x + 0.5) - 1) : ((int) (x - 0.5) - 1);
  78. }
  79.  
  80. static inline bool
  81. idx_is_inf_or_nan (double x)
  82. {
  83.   bool retval = false;
  84.  
  85.   if (xisnan (x))
  86.     {
  87.       (*current_liboctave_error_handler) ("NaN invalid as index");
  88.       retval = true;
  89.     }
  90.   else if (xisinf (x))
  91.     {
  92.       (*current_liboctave_error_handler) ("Inf invalid as index");
  93.       retval = true;
  94.     }
  95.  
  96.   return retval;
  97. }
  98.  
  99. IDX_VEC_REP::idx_vector_rep (const ColumnVector& v)
  100. {
  101.   data = 0;
  102.   initialized = 0;
  103.   frozen = 0;
  104.   colon_equiv_checked = 0;
  105.   colon_equiv = 0;
  106.   colon = 0;
  107.  
  108.   len = v.length ();
  109.  
  110.   orig_nr = len;
  111.   orig_nc = 1;
  112.  
  113.   if (len == 0)
  114.     {
  115.       num_zeros = 0;
  116.       num_ones = 0;
  117.       one_zero = 0;
  118.       max_val = 0;
  119.       min_val = 0;
  120.       initialized = 1;
  121.       return;
  122.     }
  123.   else
  124.     {
  125.       data = new int [len];
  126.  
  127.       for (int i = 0; i < len; i++)
  128.     {
  129.       double d = v.elem (i);
  130.  
  131.       if (idx_is_inf_or_nan (d))
  132.         return;
  133.       else
  134.         data[i] = tree_to_mat_idx (d);
  135.     }
  136.     }
  137.  
  138.   init_state ();
  139. }
  140.  
  141. IDX_VEC_REP::idx_vector_rep (const Matrix& m)
  142. {
  143.   data = 0;
  144.   initialized = 0;
  145.   frozen = 0;
  146.   colon_equiv_checked = 0;
  147.   colon_equiv = 0;
  148.   colon = 0;
  149.  
  150.   orig_nr = m.rows ();
  151.   orig_nc = m.columns ();
  152.  
  153.   len = orig_nr * orig_nc;
  154.  
  155.   if (len == 0)
  156.     {
  157.       num_zeros = 0;
  158.       num_ones = 0;
  159.       one_zero = 0;
  160.       max_val = 0;
  161.       min_val = 0;
  162.       initialized = 1;
  163.       return;
  164.     }
  165.   else
  166.     {
  167.       int k = 0;
  168.       data = new int [len];
  169.  
  170.       for (int j = 0; j < orig_nc; j++)
  171.     for (int i = 0; i < orig_nr; i++)
  172.       {
  173.         double d = m.elem (i, j);
  174.  
  175.         if (idx_is_inf_or_nan (d))
  176.           return;
  177.         else
  178.           data[k++] = tree_to_mat_idx (d);
  179.       }
  180.     }
  181.  
  182.   init_state ();
  183. }
  184.  
  185. IDX_VEC_REP::idx_vector_rep (double d)
  186. {
  187.   data = 0;
  188.   initialized = 0;
  189.   frozen = 0;
  190.   colon_equiv_checked = 0;
  191.   colon_equiv = 0;
  192.   colon = 0;
  193.  
  194.   len = 1;
  195.  
  196.   orig_nr = 1;
  197.   orig_nc = 1;
  198.  
  199.   if (idx_is_inf_or_nan (d))
  200.     return;
  201.   else
  202.     {
  203.       data = new int [len];
  204.  
  205.       data[0] = tree_to_mat_idx (d);
  206.     }
  207.  
  208.   init_state ();
  209. }
  210.  
  211. IDX_VEC_REP::idx_vector_rep (const Range& r)
  212. {
  213.   data = 0;
  214.   initialized = 0;
  215.   frozen = 0;
  216.   colon_equiv_checked = 0;
  217.   colon_equiv = 0;
  218.   colon = 0;
  219.  
  220.   len = r.nelem ();
  221.  
  222.   orig_nr = 1;
  223.   orig_nc = len;
  224.  
  225.   if (len < 0)
  226.     {
  227.       (*current_liboctave_error_handler) ("invalid range used as index");
  228.       return;
  229.     }
  230.   else if (len == 0)
  231.     {
  232.       num_zeros = 0;
  233.       num_ones = 0;
  234.       one_zero = 0;
  235.       max_val = 0;
  236.       min_val = 0;
  237.       initialized = 1;
  238.       return;
  239.     }
  240.  
  241.   double b = r.base ();
  242.   double step = r.inc ();
  243.  
  244.   data = new int [len];
  245.  
  246.   for (int i = 0; i < len; i++)
  247.     {
  248.       double val = b + i * step;
  249.  
  250.       if (idx_is_inf_or_nan (val))
  251.     return;
  252.       else
  253.     data[i] = tree_to_mat_idx (val);
  254.     }
  255.  
  256.   init_state ();
  257. }
  258.  
  259. IDX_VEC_REP::idx_vector_rep (char c)
  260. {
  261.   assert (c == ':');
  262.  
  263.   colon = 1;
  264.   len = 0;
  265.   num_zeros = 0;
  266.   num_ones = 0;
  267.   one_zero = 0;
  268.   initialized = 0;
  269.   frozen = 0;
  270.   colon_equiv_checked = 0;
  271.   colon_equiv = 0;
  272.   data = 0;
  273.  
  274.   init_state ();
  275. }
  276.  
  277. IDX_VEC_REP&
  278. IDX_VEC_REP::operator = (const IDX_VEC_REP& a)
  279. {
  280.   if (this != &a)
  281.     {
  282.       initialized = a.initialized;
  283.       frozen = a.frozen;
  284.       colon_equiv_checked = a.colon_equiv_checked;
  285.       colon_equiv = a.colon_equiv;
  286.  
  287.       colon = a.colon;
  288.  
  289.       orig_nr = a.orig_nr;
  290.       orig_nc = a.orig_nc;
  291.  
  292.       delete [] data;
  293.       len = a.len;
  294.       data = new int [len];
  295.       for (int i = 0; i < len; i++)
  296.     data[i] = a.data[i];
  297.  
  298.       num_zeros = a.num_zeros;
  299.       num_ones = a.num_ones;
  300.       one_zero = a.one_zero;
  301.  
  302.       max_val = a.max_val;
  303.       min_val = a.min_val;
  304.     }
  305.   return *this;
  306. }
  307.  
  308. void
  309. IDX_VEC_REP::init_state (void)
  310. {
  311.   num_zeros = 0;
  312.   num_ones = 0;
  313.  
  314.   if (colon)
  315.     {
  316.       one_zero = 0;
  317.       min_val = max_val = 0;
  318.     }
  319.   else
  320.     {
  321.       one_zero = 1;
  322.  
  323.       min_val = max_val = data[0];
  324.  
  325.       int i = 0;
  326.       do
  327.     {
  328.       if (data[i] == -1)
  329.         num_zeros++;
  330.       else if (data[i] == 0)
  331.         num_ones++;
  332.  
  333.       if (one_zero && data[i] != -1 && data[i] != 0)
  334.         one_zero = 0;
  335.  
  336.       if (data[i] > max_val)
  337.         max_val = data[i];
  338.  
  339.       if (data[i] < min_val)
  340.         min_val = data[i];
  341.     }
  342.       while (++i < len);
  343.     }
  344.  
  345.   initialized = 1;
  346. }
  347.  
  348. void
  349. IDX_VEC_REP::maybe_convert_one_zero_to_idx (int z_len, int prefer_zero_one)
  350. {
  351.   if (one_zero && z_len == len
  352.       && (num_ones != len || prefer_zero_one))
  353.     {
  354.       if (num_ones == 0)
  355.     {
  356.       len = 0;
  357.       max_val = 0;
  358.       min_val = 0;
  359.       delete [] data;
  360.       data = 0;
  361.     }
  362.       else
  363.     {
  364.       assert (num_ones + num_zeros == len);
  365.  
  366.       int *new_data = new int [num_ones];
  367.       int k = 0;
  368.       for (int i = 0; i < len; i++)
  369.         if (data[i] == 0)
  370.           new_data[k++] = i;
  371.  
  372.       delete [] data;
  373.       len = num_ones;
  374.       data = new_data;
  375.  
  376.       min_val = max_val = data[0];
  377.  
  378.       int i = 0;
  379.       do
  380.         {
  381.           if (data[i] > max_val)
  382.         max_val = data[i];
  383.  
  384.           if (data[i] < min_val)
  385.         min_val = data[i];
  386.         }
  387.       while (++i < len);
  388.     }
  389.     }
  390. }
  391.  
  392. int
  393. IDX_VEC_REP::checkelem (int n) const
  394. {
  395.   if (n < 0 || n >= len)
  396.     {
  397.       (*current_liboctave_error_handler) ("idx-vector: index out of range");
  398.       return 0;
  399.     }
  400.  
  401.   return elem (n);
  402. }
  403.  
  404. static inline int
  405. intcmp (int *ii, int *jj)
  406. {
  407.   return (*ii - *jj);
  408. }
  409.  
  410. static inline void
  411. sort_data (int *d, int l)
  412. {
  413.   qsort ((void *) d, l, sizeof (int),
  414.      (int (*)(const void*, const void*)) intcmp);
  415. }
  416.  
  417. static inline int
  418. make_uniq (int *d, int l)
  419. {
  420.   int k = 0;
  421.   for (int ii = 1; ii < l; ii++)
  422.     {
  423.       if (d[ii] != d[k])
  424.     {
  425.       k++;
  426.       d[k] = d[ii];
  427.     }
  428.     }
  429.   return k+1;
  430. }
  431.  
  432. static inline int *
  433. copy_data (const int *d, int l)
  434. {
  435.   int *new_data = new int [l];
  436.  
  437.   for (int ii = 0; ii < l; ii++)
  438.     new_data[ii] = d[ii];
  439.  
  440.   return new_data;
  441. }
  442.  
  443. int
  444. IDX_VEC_REP::is_colon_equiv (int n, int sort_uniq)
  445. {
  446.   if (! colon_equiv_checked)
  447.     {
  448.       if (colon)
  449.     {
  450.       colon_equiv = 1;
  451.     }
  452.       else if (len > 1 && ! one_zero)
  453.     {
  454.       if (sort_uniq)
  455.         {
  456.           int *tmp_data = copy_data (data, len);
  457.  
  458.           sort_data (tmp_data, len);
  459.  
  460.           int tmp_len = make_uniq (tmp_data, len);
  461.  
  462.           colon_equiv = (tmp_len == n
  463.                    && tmp_data[0] == 0
  464.                  && tmp_data[tmp_len-1] == tmp_len - 1);
  465.  
  466.           delete [] tmp_data;
  467.         }
  468.       else
  469.         {
  470.           if (len == n)
  471.         {
  472.           colon_equiv = 1;
  473.  
  474.           for (int ii = 0; ii < n; ii++)
  475.             if (data[ii] != ii)
  476.               {
  477.             colon_equiv = 0;
  478.             break;
  479.               }
  480.         }
  481.         }
  482.      }
  483.       else
  484.     colon_equiv = (len == n && (n == 0 || (n == 1 && data[0] == 0)));
  485.  
  486.       colon_equiv_checked = 1;
  487.     }
  488.  
  489.   return colon_equiv;
  490. }
  491.  
  492. void
  493. IDX_VEC_REP::sort (bool uniq)
  494. {
  495.   sort_data (data, len);
  496.  
  497.   if (uniq)
  498.     len = make_uniq (data, len);
  499. }
  500.  
  501. void
  502. IDX_VEC_REP::shorten (int n)
  503. {
  504.   if (n > 0 && n <= len)
  505.     len = n;
  506.   else
  507.     (*current_liboctave_error_handler)
  508.       ("idx_vector::shorten: internal error!");
  509. }
  510.  
  511. ostream&
  512. IDX_VEC_REP::print (ostream& os) const
  513. {
  514.   for (int ii = 0; ii < len; ii++)
  515.     os << data[ii] << "\n";
  516.   return os;
  517. }
  518.  
  519. int
  520. IDX_VEC_REP::freeze (int z_len, const char *tag,
  521.              int prefer_zero_one, int resize_ok)
  522. {
  523.   if (frozen)
  524.     {
  525.       assert (frozen_at_z_len == z_len);
  526.       return frozen_len;
  527.     }
  528.  
  529.   frozen_len = -1;
  530.  
  531.   if (colon)
  532.     frozen_len = z_len;
  533.   else
  534.     {
  535.       if (len == 0)
  536.     frozen_len = 0;
  537.       else
  538.     {
  539.       maybe_convert_one_zero_to_idx (z_len, prefer_zero_one);
  540.  
  541.       max_val = max ();
  542.       min_val = min ();
  543.  
  544.       if (min_val < 0)
  545.         {
  546.           if (tag)
  547.         (*current_liboctave_error_handler)
  548.           ("invalid %s index = %d", tag, min_val+1);
  549.           else
  550.         (*current_liboctave_error_handler)
  551.           ("invalid index = %d", min_val+1);
  552.  
  553.           initialized = 0;
  554.         }
  555.       else if (! resize_ok && max_val >= z_len)
  556.         {
  557.           if (tag)
  558.         (*current_liboctave_error_handler)
  559.           ("invalid %s index = %d", tag, max_val+1);
  560.           else
  561.         (*current_liboctave_error_handler)
  562.           ("invalid index = %d", max_val+1);
  563.  
  564.           initialized = 0;
  565.         }
  566.       else
  567.         frozen_len = length (z_len);
  568.     }
  569.     }
  570.  
  571.   frozen = 1;
  572.   frozen_at_z_len = z_len;
  573.  
  574.   return frozen_len;
  575. }
  576.  
  577. /*
  578. ;;; Local Variables: ***
  579. ;;; mode: C++ ***
  580. ;;; End: ***
  581. */
  582.